<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <link rel="stylesheet" href="docgen-resources/docgen.css" type="text/css">
  <meta name="generator" content="FreeMarker Docgen (DocBook 5)">
  <title>
    FreeMarker Manual - Directives
  </title>
    <script type="text/javascript" src="docgen-resources/jquery.js"></script>
    <script type="text/javascript" src="docgen-resources/linktargetmarker.js"></script>
</head>
<body>

    <div class="navigation">
    <div class="breadcrumb">
<span class="breadcrumb">        You are here:
          <a href="index.html">Book</a>
            <b>></b>
          <a href="pgui.html">Programmer's Guide</a>
            <b>></b>
          <a href="pgui_datamodel.html">The Data Model</a>
            <b>></b>
          Directives
</span>    </div>
    <div class="bookmarks">
<span class="bookmarks">Bookmarks:
<a href="alphaidx.html">Alpha. index</a>, <a href="gloss.html">Glossary</a>, <a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a>, <a href="ref_builtins_alphaidx.html">?builtins</a>, <a href="ref_directive_alphaidx.html">#directives</a>, <a href="ref_specvar.html">.spec_vars</a>, <a href="app_faq.html">FAQ</a>, <a href="api/index.html">API</a>, <a href="../index.html">Home</a></span>    </div>
    <div class="pagers">
      <div class="pagersVerticalSpacer"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></div>
<div class="pagerButton"><a href="pgui_datamodel_node.html"><span class="hideA">Next page: </span>Node variables</a></div><div class="pagerButton"><a href="pgui_datamodel_method.html">Previous page</a></div><div class="pagerButton"><a href="pgui_datamodel.html">Parent page</a></div><div class="pagerButton"><a href="index.html">Contents</a></div>      <div class="pagersVerticalSpacer"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></div>
    </div>
    </div>

<div id="mainContent">

  
  
  
  
  <h1 class="rank_section1"
        id="pageTopTitle">
<a name="pgui_datamodel_directive"></a>Directives  </h1>
    
    <div class="toc">
      <p>
        <b>
            Page Contents
        </b>
      </p>
      
  <ul class="noMargin">
      <li style="padding-bottom: 0.5em"><i><a href="#docgen_afterTheTOC">Intro.</a></i></li>
      <li>
        <a href="#autoid_36">Example 1</a>
      </li>
      <li>
        <a href="#autoid_37">Example 2</a>
      </li>
      <li>
        <a href="#autoid_38">Notices</a>
      </li>
  </ul>
    </div>
    <a name="docgen_afterTheTOC"></a>
    
<p>Java programmers can implement user-defined directives in Java
        using the <tt style="color: #A03D10">TemplateDirectiveModel</tt> interface. See in
        the API documentation.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
   <p class="rank_note">Note</p>

          <p><tt style="color: #A03D10">TemplateDirectiveModel</tt> was introduced in
          FreeMarker 2.3.11, replacing the soon to be depreciated
          <tt style="color: #A03D10">TemplateTransformModel</tt>.</p>
        </div>

            
  
  
  
  <h2 class="rank_section2"
        >
<a name="autoid_36"></a>Example 1  </h2>


          <p>We will implement a directive which converts all output
          between its start-tag and end-tag to upper case. Like, this
          template:</p>

          <div align="left" class="programlisting"><table bgcolor="#D8D8D8" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td><table bgcolor="#D8D8D8" cellspacing="0" cellpadding="4" border="0" width="100%" style="margin: 0px"><tr><td><pre style="margin: 0px">
foo
<b>&lt;@upper&gt;</b>
  bar
  &lt;#-- All kind of FTL is allowed here --&gt;
  &lt;#list [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;] as color&gt;
    ${color}
  &lt;/#list&gt;
  baaz
<b>&lt;/@upper&gt;</b>
wombat&nbsp;<span style="font-size: 1pt"> </span></pre></td></tr></table></td><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td>      </tr>
</table>  </div>


          <p>will output this:</p>

          <div align="left" class="programlisting"><table bgcolor="#CCFFCC" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td><table bgcolor="#CCFFCC" cellspacing="0" cellpadding="4" border="0" width="100%" style="margin: 0px"><tr><td><pre style="margin: 0px">
foo
  BAR
    RED
    GREEN
    BLUE
  BAAZ
wombat&nbsp;<span style="font-size: 1pt"> </span></pre></td></tr></table></td><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td>      </tr>
</table>  </div>


          <p>This is the source code of the directive class:</p>

          <div align="left" class="programlisting"><table bgcolor="#F8F8F8" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td><table bgcolor="#F8F8F8" cellspacing="0" cellpadding="4" border="0" width="100%" style="margin: 0px"><tr><td><pre style="margin: 0px">
package com.example;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 *  FreeMarker user-defined directive that progressively transforms
 *  the output of its nested content to upper-case.
 *  
 *  
 *  &lt;p&gt;&lt;b&gt;Directive info&lt;/b&gt;&lt;/p&gt;
 * 
 *  &lt;p&gt;Directive parameters: None
 *  &lt;p&gt;Loop variables: None
 *  &lt;p&gt;Directive nested content: Yes
 */
public class UpperDirective implements TemplateDirectiveModel {
    
    public void execute(Environment env,
            Map params, TemplateModel[] loopVars,
            TemplateDirectiveBody body)
            throws TemplateException, IOException {
        // Check if no parameters were given:
        if (!params.isEmpty()) {
            throw new TemplateModelException(
                    &quot;This directive doesn't allow parameters.&quot;);
        }
        if (loopVars.length != 0) {
                throw new TemplateModelException(
                    &quot;This directive doesn't allow loop variables.&quot;);
        }
        
        // If there is non-empty nested content:
        if (body != null) {
            // Executes the nested body. Same as &lt;#nested&gt; in FTL, except
            // that we use our own writer instead of the current output writer.
            body.render(new UpperCaseFilterWriter(env.getOut()));
        } else {
            throw new RuntimeException(&quot;missing body&quot;);
        }
    }
    
    /**
     * A {@link Writer} that transforms the character stream to upper case
     * and forwards it to another {@link Writer}.
     */ 
    private static class UpperCaseFilterWriter extends Writer {
       
        private final Writer out;
           
        UpperCaseFilterWriter (Writer out) {
            this.out = out;
        }

        public void write(char[] cbuf, int off, int len)
                throws IOException {
            char[] transformedCbuf = new char[len];
            for (int i = 0; i &lt; len; i++) {
                transformedCbuf[i] = Character.toUpperCase(cbuf[i + off]);
            }
            out.write(transformedCbuf);
        }

        public void flush() throws IOException {
            out.flush();
        }

        public void close() throws IOException {
            out.close();
        }
    }

}&nbsp;<span style="font-size: 1pt"> </span></pre></td></tr></table></td><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td>      </tr>
</table>  </div>


          <p>Now we still need to create an instance of this class, and
          make this directive available to the template with the name &quot;upper&quot;
          (or with whatever name we want) somehow. A possible solution is to
          put the directive in the data-model:</p>

          <div align="left" class="programlisting"><table bgcolor="#F8F8F8" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td><table bgcolor="#F8F8F8" cellspacing="0" cellpadding="4" border="0" width="100%" style="margin: 0px"><tr><td><pre style="margin: 0px">
root.put(&quot;upper&quot;, new com.example.UpperDirective());&nbsp;<span style="font-size: 1pt"> </span></pre></td></tr></table></td><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td>      </tr>
</table>  </div>


          <p>But typically it is better practice to put commonly used
          directives into the <tt style="color: #A03D10">Configuration</tt> as <a href="pgui_config_sharedvariables.html">shared
          variables</a>.</p>

          <p>It is also possible to put the directive into an FTL library
          (collection of macros and like in a template, that you
          <tt style="color: #A03D10">include</tt> or <tt style="color: #A03D10">import</tt> in other
          templates) using the <a href="ref_builtins_expert.html#ref_builtin_new"><tt>new</tt>
          built-in</a>:</p>

          <div align="left" class="programlisting"><table bgcolor="#D8D8D8" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td><table bgcolor="#D8D8D8" cellspacing="0" cellpadding="4" border="0" width="100%" style="margin: 0px"><tr><td><pre style="margin: 0px">
&lt;#-- Maybe you have directives that you have implemented in FTL --&gt;
&lt;#macro something&gt;
  ...
&lt;/#macro&gt;

&lt;#-- Now you can't use &lt;#macro upper&gt;, but instead you can: --&gt;
&lt;#assign upper = &quot;com.example.UpperDirective&quot;?new()&gt;&nbsp;<span style="font-size: 1pt"> </span></pre></td></tr></table></td><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td>      </tr>
</table>  </div>

        
            
  
  
  
  <h2 class="rank_section2"
        >
<a name="autoid_37"></a>Example 2  </h2>


          <p>We will create a directive that executes its nested content
          again and again for the specified number of times (similarly to
          <tt style="color: #A03D10">list</tt> directive), optionally separating the the
          output of the repetations with a <tt style="color: #A03D10">&lt;hr&gt;</tt>-s.
          Let's call this directive &quot;repeat&quot;. Example template:</p>

          <div align="left" class="programlisting"><table bgcolor="#D8D8D8" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td><table bgcolor="#D8D8D8" cellspacing="0" cellpadding="4" border="0" width="100%" style="margin: 0px"><tr><td><pre style="margin: 0px">
&lt;#assign x = 1&gt;

<b>&lt;@repeat count=4&gt;</b>
  Test ${x}
  &lt;#assign x = x + 1&gt;
<b>&lt;/@repeat&gt;</b>

<b>&lt;@repeat count=3 hr=true&gt;</b>
  Test
<b>&lt;/@repeat&gt;</b>

<b>&lt;@repeat count=3; cnt&gt;</b>
  ${cnt}. Test
<b>&lt;/@repeat&gt;</b>&nbsp;<span style="font-size: 1pt"> </span></pre></td></tr></table></td><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td>      </tr>
</table>  </div>


          <p>Output:</p>

          <div align="left" class="programlisting"><table bgcolor="#CCFFCC" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td><table bgcolor="#CCFFCC" cellspacing="0" cellpadding="4" border="0" width="100%" style="margin: 0px"><tr><td><pre style="margin: 0px">
  Test 1
  Test 2
  Test 3
  Test 4

  Test
&lt;hr&gt;  Test
&lt;hr&gt;  Test

  1. Test
  2. Test
  3. Test
 &nbsp;<span style="font-size: 1pt"> </span></pre></td></tr></table></td><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td>      </tr>
</table>  </div>


          <p>The class:</p>

          <div align="left" class="programlisting"><table bgcolor="#F8F8F8" cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td><table bgcolor="#F8F8F8" cellspacing="0" cellpadding="4" border="0" width="100%" style="margin: 0px"><tr><td><pre style="margin: 0px">
package com.example;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;

import freemarker.core.Environment;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateNumberModel;

/**
 * FreeMarker user-defined directive for repeating a section of a template,
 * optionally with separating the output of the repetations with
 * &lt;tt&gt;&amp;lt;hr&gt;&lt;/tt&gt;-s.
 *
 * 
 * &lt;p&gt;&lt;b&gt;Directive info&lt;/b&gt;&lt;/p&gt;
 * 
 * &lt;p&gt;Parameters:
 * &lt;ul&gt;
 *   &lt;li&gt;&lt;code&gt;count&lt;/code&gt;: The number of repetations. Required!
 *       Must be a non-negative number. If it is not a whole number then it will
 *       be rounded &lt;em&gt;down&lt;/em&gt;.
 *   &lt;li&gt;&lt;code&gt;hr&lt;/code&gt;: Tells if a HTML &quot;hr&quot; element could be printed between
 *       repetations. Boolean. Optional, defaults to &lt;code&gt;false&lt;/code&gt;. 
 * &lt;/ul&gt;
 *
 * &lt;p&gt;Loop variables: One, optional. It gives the number of the current
 *    repetation, starting from 1.
 * 
 * &lt;p&gt;Nested content: Yes
 */
public class RepeatDirective implements TemplateDirectiveModel {
    
    private static final String PARAM_NAME_COUNT = &quot;count&quot;;
    private static final String PARAM_NAME_HR = &quot;hr&quot;;
    
    public void execute(Environment env,
            Map params, TemplateModel[] loopVars,
            TemplateDirectiveBody body)
            throws TemplateException, IOException {
        
        // ---------------------------------------------------------------------
        // Processing the parameters:
        
        int countParam = 0;
        boolean countParamSet = false;
        boolean hrParam = false;
        
        Iterator paramIter = params.entrySet().iterator();
        while (paramIter.hasNext()) {
            Map.Entry ent = (Map.Entry) paramIter.next();
            
            String paramName = (String) ent.getKey();
            TemplateModel paramValue = (TemplateModel) ent.getValue();
            
            if (paramName.equals(PARAM_NAME_COUNT)) {
                if (!(paramValue instanceof TemplateNumberModel)) {
                    throw new TemplateModelException(
                            &quot;The \&quot;&quot; + PARAM_NAME_HR + &quot;\&quot; parameter &quot;
                            + &quot;must be a number.&quot;);
                }
                countParam = ((TemplateNumberModel) paramValue)
                        .getAsNumber().intValue();
                countParamSet = true;
                if (countParam &lt; 0) {
                    throw new TemplateModelException(
                            &quot;The \&quot;&quot; + PARAM_NAME_HR + &quot;\&quot; parameter &quot;
                            + &quot;can't be negative.&quot;);
                }
            } else if (paramName.equals(PARAM_NAME_HR)) {
                if (!(paramValue instanceof TemplateBooleanModel)) {
                    throw new TemplateModelException(
                            &quot;The \&quot;&quot; + PARAM_NAME_HR + &quot;\&quot; parameter &quot;
                            + &quot;must be a boolean.&quot;);
                }
                hrParam = ((TemplateBooleanModel) paramValue)
                        .getAsBoolean();
            } else {
                throw new TemplateModelException(
                        &quot;Unsupported parameter: &quot; + paramName);
            }
        }
        if (!countParamSet) {
                throw new TemplateModelException(
                        &quot;The required \&quot;&quot; + PARAM_NAME_COUNT + &quot;\&quot; paramter&quot;
                        + &quot;is missing.&quot;);
        }
        
        if (loopVars.length &gt; 1) {
                throw new TemplateModelException(
                        &quot;At most one loop variable is allowed.&quot;);
        }
        
        // Yeah, it was long and boring...
        
        // ---------------------------------------------------------------------
        // Do the actual directive execution:
        
        Writer out = env.getOut();
        if (body != null) {
            for (int i = 0; i &lt; countParam; i++) {
                // Prints a &lt;hr&gt; between all repetations if the &quot;hr&quot; parameter
                // was true:
                if (hrParam &amp;&amp; i != 0) {
                    out.write(&quot;&lt;hr&gt;&quot;);
                }
                
                // Set the loop variable, if there is one:
                if (loopVars.length &gt; 0) {
                    loopVars[0] = new SimpleNumber(i + 1);
                }
                
                // Executes the nested body (same as &lt;#nested&gt; in FTL). In this
                // case we don't provide a special writer as the parameter:
                body.render(env.getOut());
            }
        }
    }

}&nbsp;<span style="font-size: 1pt"> </span></pre></td></tr></table></td><td width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td></tr><tr valign="top"><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td><td height="1" width="1" bgcolor="black"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></td>      </tr>
</table>  </div>

        
            
  
  
  
  <h2 class="rank_section2"
        >
<a name="autoid_38"></a>Notices  </h2>


          <p>It's important that a
          <tt style="color: #A03D10">TemplateDirectiveModel</tt> object usually should not
          be stateful. The typical mistake is the storing of the state of the
          directive call execution in the fields of the object. Think of
          nested calls of the same directive, or directive objects used as
          shared variables accessed by multiple threads concurrently.</p>

          <p>Unfortunatelly, <tt style="color: #A03D10">TemplateDirectiveModel</tt>-s
          don't support passing parameters by position (rather than by name).
          This is fixed starting from FreeMarker 2.4.</p>
          
</div>

    <div class="navigation">
    <div class="pagers">
      <div class="pagersVerticalSpacer"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></div>
<div class="pagerButton"><a href="pgui_datamodel_node.html"><span class="hideA">Next page: </span>Node variables</a></div><div class="pagerButton"><a href="pgui_datamodel_method.html">Previous page</a></div><div class="pagerButton"><a href="pgui_datamodel.html">Parent page</a></div><div class="pagerButton"><a href="index.html">Contents</a></div>      <div class="pagersVerticalSpacer"><img src="docgen-resources/img/none.gif" width="1" height="1" alt="" hspace="0" vspace="0" border="0"/></div>
    </div>
    <div class="breadcrumb">
<span class="breadcrumb">        You are here:
          <a href="index.html">Book</a>
            <b>></b>
          <a href="pgui.html">Programmer's Guide</a>
            <b>></b>
          <a href="pgui_datamodel.html">The Data Model</a>
            <b>></b>
          Directives
</span>    </div>
    </div>

<table border=0 cellspacing=0 cellpadding=0 width="100%">
    <tr>
      <td colspan=2><img src="docgen-resources/img/none.gif" width=1 height=8 alt=""></td>
    <tr>
      <td align="left" valign="top"><span class="smallFooter">
            FreeMarker Manual -- For FreeMarker 2.3.20
            <br>
          HTML generated: 2013-06-27 20:54:33 GMT
      </span></td>
      <td align="right" valign="top"><span class="smallFooter">
          <a href="http://www.xmlmind.com/xmleditor/">
            <img src="docgen-resources/img/xxe.gif" alt="Edited with XMLMind XML Editor">
          </a>
      </span></td>
    </tr>
</table>
  <!-- Put pre-loaded images here: -->
  <div style="display: none">
    <img src="docgen-resources/img/linktargetmarker.gif" alt="Here!" />
  </div>
</body>
</html>

